package ru.urfc.portal.dao.impl;

import java.util.List;

import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.Query;

import ru.urfc.portal.dao.TmpContragentDao;
import ru.urfc.portal.model.Client;
import ru.urfc.portal.model.Branch;
import ru.urfc.portal.model.TmpContragent;
import ru.urfc.portal.model.accounting.Contragent;

@Stateless
@TransactionAttribute(TransactionAttributeType.MANDATORY)
public class TmpContragentDaoImpl extends BaseDao implements TmpContragentDao {
	
	@Override
	public void createTmpContragents(Long operationId, Branch branch, List<Contragent> contragents) {
		if (contragents.size() == 0) {
			return;
		}
		StringBuilder queryStr = new StringBuilder(format(
				"INSERT INTO {0} (operationId, branch_id, contragentId, name, inn, ogrn) VALUES ", TmpContragent.class.getSimpleName()));
		boolean first = true;
		for (Contragent contragent: contragents) {
			if (!first) {
				queryStr.append(", ");
			}
			queryStr.append(format("({0}, {1}, {2}, {3}, {4}, {5})",
					operationId.toString(), branch.getId().toString(), contragent.getId().toString(), 
					strOrNull(contragent.getName()), strOrNull(contragent.getInn()), strOrNull(contragent.getOgrn())));
			first = false;
		}
		Query query = getTmpContragentEntitymanager().createNativeQuery(queryStr.toString());
		query.executeUpdate();
	}

	private String strOrNull(String str) {
		return str == null? "NULL": "'" + str + "'";
	}

	@Override
	public void updateTmpContragents(Long operationId) {
		Query query = getTmpContragentEntitymanager().createNativeQuery(format(
				"UPDATE {0} tmp" +
				" SET client_id = (SELECT client.id FROM {1} client WHERE " +
				"  tmp.contragentId = client.contragentId AND tmp.branch_id = client.branch_id)" +
				" WHERE operationId = ?",
				TmpContragent.class.getSimpleName(), Client.class.getSimpleName()));
		query.setParameter(1, operationId);
		query.executeUpdate();
		evictAll(operationId);
	}

	private void evictAll(Long operationId) {
		getTmpContragentEntitymanager().flush();
		getTmpContragentEntitymanager().clear();
	}
	
	@Override
	public Long generateOperationId() {
		TmpContragent tmp = new TmpContragent();
		EntityManager entityManager = getTmpContragentEntitymanager();
		entityManager.persist(tmp);
		entityManager.flush();
		Long result = tmp.getId();
		entityManager.remove(tmp);
		return result;
	}

	private EntityManager getTmpContragentEntitymanager() {
		return choseEntityManager(null, TmpContragent.class);
	}

}
